﻿using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Collections.ObjectModel;

using Matchingo.Common.Constants;
using Matchingo.Common.Types.Types;

namespace Matchingo.Common.Types.Types
{
    /// <summary>
    /// Represents a basic Game instance
    /// </summary>
    [DataContract]
    public class Game
    {
        private const string DEFAULT_PLAYER_NAME = CommonConstants.GAME_SETTINGS_DEFAULT_PLAYERNAME;
        private const int GAME_RECORD_CURRENT_VERSION = CommonConstants.GAME_RECORD_VERSION_CURRENT;

        #region ========== Public Enumerations ==========

        public enum GameStateEnum
        {
            Created,
            Started,
            Ended
        }

        #endregion

        #region ========== Public Properties ==========

        [DataMember]
        public int RecordVersion { get; set; }

        [DataMember]
        public Guid UniqueID { get; set; }

        [DataMember]
        public ObservableCollection<Card> CardsSet { get; set; }

        [DataMember]
        public GameStateEnum GameState { get; set; }

        // TODO:: need to combine artificial and replay game bools.. right now artificial and replay are true for replay games

        [DataMember]
        public bool ArtificialGame { get; set; }

        [DataMember]
        public bool ReplayGame { get; set; }

        [DataMember]
        public int CardCount { get; set; }

        [DataMember]
        public int TurnCount { get; set; }

        [DataMember]
        public int Score { get; set; }

        [DataMember]
        public DateTime? StartTime { get; set; }

        [DataMember]
        public DateTime? EndTime { get; set; }

        [DataMember]
        public string PlayerName { get; set; }

		/// <summary>
		/// Gets or sets the facebook user ID - needed for button binding on HighScoreView
		/// </summary>
		/// <value>The FB user ID.</value>
		public string FBUserID { get; set; }

        // we are going to store a history of all combos achieved - this will be used as a multiplier 
        // when calculating the score.. if a user were to get 2 in a row, then another (making 3) they would have
        // 2 and 3 in their combo history
        [DataMember]
        public List<int> ComboHistory { get; set; }

        [DataMember]
        public List<CardFlipCommand> GameFlipCommands;

        public TimeSpan GameTimeElapsed
        {
            get
            {
                // if the game hasnt started then the time is 0
                if (StartTime == null)
                    return new TimeSpan(0, 0, 0);

                // if the game is over then use that, if not then use now                
                if (EndTime == null)
                {
                    return DateTime.Now - StartTime.Value;
                }

                return EndTime.Value - StartTime.Value;
            }
        }

        #endregion

        #region ========== Constructor ==========

        public Game()
        {
            UniqueID = Guid.NewGuid();
            RecordVersion = GAME_RECORD_CURRENT_VERSION;
            PlayerName = DEFAULT_PLAYER_NAME;
            ArtificialGame = true;
            CardCount = 0;
            TurnCount = 0;
            Score = 0;
            GameState = GameStateEnum.Created;
            StartTime = null; // will get set on first card flip
            EndTime = null;
            CardsSet = null; // set when the game is created

            GameFlipCommands = new List<CardFlipCommand>();
            ComboHistory = new List<int>();
        }

        #endregion

    }
}
